package com.tian.mongo.service;

import com.tian.dto.message.*;
import com.tian.entity.User;
import com.tian.enums.ResultCode;
import com.tian.enums.SystemUserMessageStatusEnum;
import com.tian.exception.BusinessException;
import com.tian.mongo.domain.UserMessage;
import com.tian.mongo.repository.UserMessageRepository;
import com.tian.util.CommonResult;
import com.tian.util.SnowflakeIdWorker;
import com.tian.util.UserCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * {@code @description:} 用户站内信
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024/1/13 11:19
 * {@code @version:} 1.0
 */

@Slf4j
@Service
public class UserMessageService {

    @Resource
    private UserMessageRepository userMessageRepository;
    @Resource
    private MongoTemplate mongoTemplate;


    public void saveUser(UserMessage userMessage) {
        userMessage.setId(SnowflakeIdWorker.getLong());
        userMessageRepository.save(userMessage);
    }

    /**
     * 我的列表
     *
     * @param recordPageReqDto 请求参数
     * @return 站内信列表
     */
    public CommonResult<SystemUserMessagePageRespDto> page(SystemUserMessageRecordPageReqDto recordPageReqDto) {
        SystemUserMessagePageRespDto systemUserMessagePageRespDto = new SystemUserMessagePageRespDto();
        User user = UserCacheUtil.getUser();
        Criteria criteria1 = new Criteria("receiverId").is(user.getId()); // 创建第一个条件，名字相等
        Criteria criteria2;
        if (recordPageReqDto.getStatus() != null) {
            criteria2 = new Criteria("status").is(recordPageReqDto.getStatus());
        } else {
            criteria2 = new Criteria("status").in(SystemUserMessageStatusEnum.READ.getStatus(), SystemUserMessageStatusEnum.UN_READ.getStatus());
        }
        Query query = Query.query(criteria1).addCriteria(criteria2);

        long count = mongoTemplate.count(query, UserMessage.class);
        if (count == 0) {
            return CommonResult.success(systemUserMessagePageRespDto);
        }

        systemUserMessagePageRespDto.setTotal(count);
        systemUserMessagePageRespDto.setPage(recordPageReqDto.getPage());
        systemUserMessagePageRespDto.setPageSize(recordPageReqDto.getPageSize());

        query.skip((long) recordPageReqDto.getPage() * recordPageReqDto.getPageSize());
        query.limit(recordPageReqDto.getPageSize());
        List<UserMessage> userMessageList = mongoTemplate.find(query, UserMessage.class);

        List<SystemUserMessageRespDto> dataList = new ArrayList<>();
        for (UserMessage userMessage : userMessageList) {
            SystemUserMessageRespDto systemUserMessageRespDto = new SystemUserMessageRespDto();
            BeanUtils.copyProperties(userMessage, systemUserMessageRespDto);
            systemUserMessageRespDto.setStatusStr(SystemUserMessageStatusEnum.getSystemUserMessageStatusEnumByStatus(userMessage.getStatus()).getDesc());
            dataList.add(systemUserMessageRespDto);
        }
        systemUserMessagePageRespDto.setDataList(dataList);
        return CommonResult.success(systemUserMessagePageRespDto);
    }

    /**
     * 阅读站内信
     *
     * @param recordUpdateReqDto 请求参数
     * @return 是否阅读成功
     */
    public CommonResult<SystemUserMessageUpdateRespDto> read(SystemUserMessageRecordUpdateReqDto recordUpdateReqDto) {
        User user = UserCacheUtil.getUser();
        UserMessage userMessage = userMessageRepository.findById(recordUpdateReqDto.getId()).orElse(null);
        if (userMessage == null || !Objects.equals(userMessage.getReceiverId(), user.getId())) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        userMessage.setId(1195884031271501824L);
        userMessage.setStatus(1);
        userMessageRepository.save(userMessage);
        return CommonResult.success();
    }

    /**
     * 全部阅读
     */
    public CommonResult<SystemUserMessageUpdateRespDto> readAll() {
        User user = UserCacheUtil.getUser();
        List<UserMessage> userMessageList = userMessageRepository.findByReceiverId(user.getId());
        for (UserMessage userMessage : userMessageList) {
            userMessage.setStatus(SystemUserMessageStatusEnum.READ.getStatus());
            userMessage.setCreateTime(new Date());
            userMessageRepository.save(userMessage);
        }
        return CommonResult.success();
    }

    public CommonResult<SystemUserMessageUpdateRespDto> delete(SystemUserMessageRecordUpdateReqDto recordUpdateReqDto) {
        User user = UserCacheUtil.getUser();
        UserMessage userMessage = userMessageRepository.findById(1195884031271501824L).orElse(null);
        if (userMessage == null || !Objects.equals(userMessage.getReceiverId(), user.getId())) {
            throw new BusinessException(ResultCode.FORBIDDEN);
        }
        userMessage.setId(recordUpdateReqDto.getId());
        userMessage.setStatus(SystemUserMessageStatusEnum.DELETE.getStatus());
        userMessageRepository.save(userMessage);
        return CommonResult.success();
    }

    /**
     * 通过主键id查询站内信内容
     *
     * @param id 主键id
     * @return 站内信内容
     */
    public CommonResult<SystemUserMessageRespDto> queryById(Long id) {
        if (userMessageRepository.existsById(id)) {
            Optional<UserMessage> byId = userMessageRepository.findById(id);
            UserMessage userMessage = byId.get();
            SystemUserMessageRespDto systemUserMessageRespDto = new SystemUserMessageRespDto();
            BeanUtils.copyProperties(userMessage, systemUserMessageRespDto);
            systemUserMessageRespDto.setStatusStr(SystemUserMessageStatusEnum.getSystemUserMessageStatusEnumByStatus(userMessage.getStatus()).getDesc());
            return CommonResult.success(systemUserMessageRespDto);
        }
        throw new BusinessException(ResultCode.FORBIDDEN);
    }
}

